"""通知公告表(SysNotice)的Pydantic模型

包含用于API接口的Base、Create、Update、Public模型
"""

from datetime import datetime
from typing import List, Optional

from pydantic import Field, field_serializer, field_validator

from app.schemas.base import BaseSchema


class NoticeBase(BaseSchema):
    """通知公告表基础模型"""

    type: int = Field(description="通知类型（关联字典编码：notice_type）", alias="type")
    level: str = Field(max_length=5, description="通知等级（字典code：notice_level）", alias="level")
    target_type: int = Field(description="目标类型（1: 全体, 2: 指定）", alias="targetType")
    title: Optional[str] = Field(default=None, max_length=50, description="通知标题", alias="title")
    content: Optional[str] = Field(default=None, description="通知内容", alias="content")
    target_user_ids: Optional[str] = Field(
        default=None, max_length=255, description="目标人ID集合（多个使用英文逗号,分割）", alias="targetUserIds"
    )


class NoticeCreate(NoticeBase):
    """创建通知公告表时使用的模型"""

    create_by: int = Field(description="创建人ID")


class NoticeUpdate(NoticeBase):
    """更新通知公告表时使用的模型"""

    type: Optional[int] = Field(default=None, description="通知类型（关联字典编码：notice_type）", alias="type")
    level: Optional[str] = Field(
        default=None, max_length=5, description="通知等级（字典code：notice_level）", alias="level"
    )
    target_type: Optional[int] = Field(default=None, description="目标类型（1: 全体, 2: 指定）", alias="targetType")
    title: Optional[str] = Field(default=None, max_length=50, description="通知标题", alias="title")
    content: Optional[str] = Field(default=None, description="通知内容", alias="content")
    target_user_ids: Optional[str] = Field(
        default=None, max_length=255, description="目标人ID集合（多个使用英文逗号,分割）", alias="targetUserIds"
    )
    publisher_id: Optional[int] = Field(default=None, description="发布人ID", alias="publisherId")
    publish_status: Optional[int] = Field(
        default=None, description="发布状态（0: 未发布, 1: 已发布, -1: 已撤回）", alias="publishStatus"
    )


class NoticePublic(NoticeBase):
    """通知公告表公开模型，用于API响应"""

    id: int = Field(alias="id", description="ID")
    type: int = Field(alias="type", description="通知类型（关联字典编码：notice_type）")
    level: str = Field(alias="level", description="通知等级（字典code：notice_level）")
    target_type: int = Field(alias="targetType", description="目标类型（1: 全体, 2: 指定）")
    create_by: int = Field(alias="createBy", description="创建人ID")
    create_time: datetime = Field(alias="createTime", description="创建时间")
    title: Optional[str] = Field(default=None, alias="title", description="通知标题")
    content: Optional[str] = Field(default=None, alias="content", description="通知内容")
    target_user_ids: Optional[str] = Field(
        default=None, alias="targetUserIds", description="目标人ID集合（多个使用英文逗号,分割）"
    )
    publisher_id: Optional[int] = Field(default=None, alias="publisherId", description="发布人ID")
    publish_status: Optional[int] = Field(
        default=None, alias="publishStatus", description="发布状态（0: 未发布, 1: 已发布, -1: 已撤回）"
    )
    publish_time: Optional[datetime] = Field(default=None, alias="publishTime", description="发布时间")
    revoke_time: Optional[datetime] = Field(default=None, alias="revokeTime", description="撤回时间")
    update_by: Optional[int] = Field(default=None, alias="updateBy", description="更新人ID")
    update_time: Optional[datetime] = Field(default=None, alias="updateTime", description="更新时间")


class NoticePageVO(BaseSchema):
    """通知公告分页列表"""

    id: Optional[int] = Field(None, description="通知ID", alias="id")
    title: Optional[str] = Field(None, description="通知标题", alias="title")
    publish_status: Optional[int] = Field(None, description="通知状态", alias="publishStatus")
    type: Optional[int] = Field(None, description="通知类型", alias="type")
    publisher_name: Optional[str] = Field(None, description="发布人姓名", alias="publisherName")
    level: Optional[str] = Field(None, description="通知等级", alias="level")
    publish_time: Optional[datetime] = Field(description="发布时间", alias="publishTime")
    is_read: Optional[int] = Field(description="是否已读", alias="isRead")
    target_type: Optional[int] = Field(description="目标类型", alias="targetType")
    create_time: Optional[datetime] = Field(description="创建时间", alias="createTime")
    revoke_time: Optional[datetime] = Field(description="撤回时间", alias="revokeTime")

    @field_serializer("publish_time", "revoke_time", "create_time", when_used="json")
    def serialize_dt(self, dt: datetime, _info):
        return dt.strftime("%Y-%m-%d %H:%M")


class NoticeDetailVO(BaseSchema):
    """阅读通知公告VO"""

    id: int = Field(description="通知ID", alias="id")
    title: str = Field(description="通知标题", alias="title")
    content: str = Field(description="通知内容", alias="content")
    type: int = Field(description="通知类型", alias="type")
    publisher_name: str = Field(description="发布人姓名", alias="publisherName")
    level: str = Field(description="优先级(L-低 M-中 H-高)", alias="level")
    publish_status: int = Field(
        description="发布状态(0-未发布 1已发布 2已撤回) 冗余字段，方便判断是否已经发布", alias="publishStatus"
    )
    publish_time: datetime = Field(description="发布时间", alias="publishTime")

    @field_serializer("publish_time", when_used="json")
    def serialize_dt(self, dt: datetime, _info):
        return dt.strftime("%Y-%m-%d %H:%M")


class NoticeForm(BaseSchema):
    """通知公告表单对象"""

    id: Optional[int] = Field(default=None, alias="id", description="通知ID")
    title: Optional[str] = Field(default=None, alias="title", description="通知标题", max_length=50)
    content: Optional[str] = Field(default=None, alias="content", description="通知内容", max_length=65535)
    type: Optional[int] = Field(default=None, alias="type", description="通知类型")
    level: Optional[str] = Field(default=None, alias="level", description="优先级(L-低 M-中 H-高)")
    target_type: Optional[int] = Field(default=None, alias="targetType", description="目标类型(1-全体 2-指定)")
    target_user_ids: Optional[List[str]] = Field(default=None, alias="targetUserIds", description="接收人ID集合")

    @field_validator("content")
    def validate_content(cls, value: str) -> str:
        """验证通知内容"""
        if not value.strip():
            raise ValueError("通知内容不能为空")
        return value

    @field_validator("title")
    def validate_title(cls, value: str) -> str:
        """验证通知标题"""
        if not value.strip():
            raise ValueError("通知标题不能为空")
        return value


class UserNoticePageVO(BaseSchema):
    """用户公告VO"""

    id: int = Field(description="通知ID", alias="id")
    title: str = Field(description="通知标题", alias="title")
    type: int = Field(description="通知类型", alias="type")
    level: str = Field(description="通知等级", alias="level")
    publisher_name: str = Field(description="发布人姓名", alias="publisherName")
    publish_time: datetime = Field(description="发布时间", alias="publishTime")
    is_read: int = Field(description="是否已读", alias="isRead")

    @field_serializer("publish_time", when_used="json")
    def serialize_dt(self, dt: datetime, _info):
        return dt.strftime("%Y-%m-%d %H:%M")
